package com.simple.trade.controller.vm;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.simple.common.entity.controller.BaseController;
import com.simple.trade.service.vm.RedirectService;
import lombok.SneakyThrows;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.AbstractMap;
import java.util.Enumeration;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 这个作用是渠道跳转到我们
 *
 * @author yasud
 * @date 2020年10月13日 09:09
 * @description
 */
@Controller
@RequestMapping("/redirect")
public class RedirectController extends BaseController {

    @Autowired
    ObjectMapper objectMapper;

    @Autowired
    RedirectService redirectService;

    /**
     * 动态跳转, 固定跳转都可以从这里跳转
     * /api/pay/redirect/1/c123/abc;a=1;b=2
     *
     * @param channelFlag
     * @return
     */
    @GetMapping("/{channelFlag}/{flag}")
    public void redirectDynamic(@PathVariable String channelFlag,
                                @PathVariable String flag,
                                @MatrixVariable(pathVar = "flag", required = false) Map<String, String> pathParam,
                                HttpServletRequest request,
                                HttpServletResponse response) throws IOException {
        Map<Object, Object> param = getParam(request);
        if (MapUtils.isNotEmpty(pathParam)) {
            param.putAll(pathParam);
        }
        String url = redirectService.redirectDynamic(channelFlag, flag, param, getHeader(request));
        if (StringUtils.isNotBlank(url)) {
            response.sendRedirect(url);
        }
        else {
            buildEmptyPage(response);
        }
    }

    @SneakyThrows
    private void buildEmptyPage(HttpServletResponse response) {
        response.setContentType(MediaType.TEXT_HTML_VALUE);
        PrintWriter writer = response.getWriter();
        writer.println("<html></html>");
        writer.close();
    }

    /**
     * 可自定义输出, 但是对于这种可以自定义输出的只能是动态生成的
     * @param flag
     * @param pathParam
     * @param request
     * @param response
     * @return
     * @throws JsonProcessingException
     */
    @GetMapping("/infiltration/{channelFlag}/{flag}")
    public ResponseEntity infiltration(@PathVariable String channelFlag,
                                       @PathVariable String flag,
                                       @MatrixVariable(pathVar = "flag", required = false) Map<String, String> pathParam,
                                       HttpServletRequest request,
                                       HttpServletResponse response) throws JsonProcessingException {
        Map<Object, Object> param = getParam(request);
        if (MapUtils.isNotEmpty(pathParam)) {
            param.putAll(pathParam);
        }
        Pair<MediaType, Object> pair = redirectService.infiltration(channelFlag, flag, param, getHeader(request));
        Object body = pair.getRight();
        return ResponseEntity.accepted()
                .contentType(pair.getKey())
                .body(body);
    }

    /**
     * 获取参数
     *
     * @param request
     * @return
     */
    private Map<Object, Object> getParam(HttpServletRequest request) throws JsonProcessingException {
        Stream<Map.Entry<String, String[]>> stream = request.getParameterMap().entrySet().stream();
        Map<Object, Object> collect = stream.filter(stringEntry -> {
            String[] value = stringEntry.getValue();
            return Objects.nonNull(value) && value.length >= 1;
        }).map(stringEntry -> {
            String key = stringEntry.getKey();
            String[] value = stringEntry.getValue();
            if (value.length > 1) {
                return new AbstractMap.SimpleEntry(key, value);
            } else {
                return new AbstractMap.SimpleEntry(key, value[0]);
            }
        }).collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue()));
        return collect;
    }

    /**
     * 得到头
     *
     * @param request
     * @return
     * @throws JsonProcessingException
     */
    private Map<Object, Object> getHeader(HttpServletRequest request) throws JsonProcessingException {
        Enumeration<String> headerNames = request.getHeaderNames();
        Map<Object, Object> collect = Lists.newArrayList(Iterators.forEnumeration(headerNames)).stream().filter(s -> {
            return StringUtils.isNotBlank(request.getHeader(s));
        }).map(s -> {
            return new AbstractMap.SimpleEntry(s, request.getHeader(s));
        }).collect(Collectors.toMap(simpleEntry -> simpleEntry.getKey(), simpleEntry -> simpleEntry.getValue()));
        return collect;
    }
}
